const assert = require('assert')

/**
 * Eva interpreter
 */
class Eva {
    eval(exp) {
        if (isNumber(exp)) {
            return exp
        }

        if (isString(exp)) {
            // "hello" -> hello
            return exp.slice(1, -1);
        }

        if (exp[0] === '+') {
            // (+ 1 2) -> 3
            return exp[1] + exp[2]
        }
        throw 'Unimplemented'
    }
}

function isNumber(exp) {
    return typeof exp === 'number'
}

function isString(exp) {
    return typeof exp === 'string' && exp[0] === '"' && exp.slice(-1) === '"'
}

// ----- -----
// tests:
const eva = new Eva();

// Self-evaluating 自求值(评估) -> 对应字面量, 编译器不做处理直接返回字面量本身
assert.strictEqual(eva.eval(1), 1)
assert.strictEqual(eva.eval('"hello"'), 'hello')

assert.strictEqual(eva.eval(['+', 1, 5]), 6)
assert.strictEqual(eva.eval(['+', ['+', 3, 2], 5]), 10)

console.log('All assertions passed!')